package com.ding.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ding.manager.config.DTConstant;
import com.ding.manager.config.DicType;
import com.ding.manager.service.ApproveService;
import com.ding.manager.util.PageData;
import com.dingtalk.api.request.OapiProcessinstanceCreateRequest;
import com.dingtalk.api.response.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

import static com.ding.manager.config.DTConstant.resCode;


@Service("approveService")
public class ApproveServiceImpl implements ApproveService {

    protected Logger logger = Logger.getLogger(this.getClass());


    @Override
    public void insertInstance(PageData pd) throws Exception{

        List<OapiProcessinstanceCreateRequest.FormComponentValueVo> formComponentValues  = new ArrayList<OapiProcessinstanceCreateRequest.FormComponentValueVo>();
        OapiProcessinstanceCreateRequest.FormComponentValueVo vo = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        vo.setName("项目名称"); //单行输入框
        vo.setValue(pd.getString("projectName"));
        formComponentValues.add(vo);

        vo = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        vo.setName("详细需求"); //多行输入框
        vo.setValue(pd.getString("customersNeeds"));
        formComponentValues.add(vo);

        vo = new OapiProcessinstanceCreateRequest.FormComponentValueVo();
        vo.setName("附件");       //附件格式
        JSONArray ja = new JSONArray();
        JSONObject jo = new JSONObject();
        jo.put("spaceId","848635913");
        jo.put("fileName","客户需求调研表");
//        jo.put("fileSize","35264");
//        jo.put("fileType","xlsx");
        jo.put("fileId","3486803033");
        ja.add(jo);
        vo.setValue(ja.toJSONString());
        formComponentValues.add(vo);


        OapiProcessinstanceCreateResponse response = DTConstant.createInstance(null,null,0L,formComponentValues);
        if(response.getErrcode().equals(resCode)){
            pd.put("instanceId",response.getProcessInstanceId());
        }else {
            logger.error("提交立项申请 接口请求失败");
            throw new Exception();
        }
    }

    @Override
    public void updateProjStatus(String instanceId) throws Exception {
        //查看状态是否需要修改
//        String projStatus = (String) dao.findForObject("ApproveMapper.getProjStatus", instanceId);
        String projStatus = "";
        if (null!=projStatus&&(projStatus.equals(DicType.instance_running)||projStatus.equals(DicType.instance_inapprove))) {   //待审批或者审批中可以继续
            PageData pd = new PageData();
            pd.put("instanceId",instanceId);
            //查询任务最新信息修改任务状态
            OapiProcessinstanceGetResponse res = DTConstant.getProjectDetail(instanceId);
            if (res.getErrcode().equals(DTConstant.resCode)) {
                String dUserId = "";
                List<OapiProcessinstanceGetResponse.OperationRecordsVo> records = res.getProcessInstance().getOperationRecords();
                if (null != records && !records.isEmpty()) {
                    for (OapiProcessinstanceGetResponse.OperationRecordsVo vo : records) {
                        if (vo.getOperationType().equals("EXECUTE_TASK_NORMAL")) {
                            pd.put("updateTime",vo.getDate());
                            pd.put("status",DicType.instance_inapprove); //有这种type说明是审批中
                            dUserId = vo.getUserid();
                        }
                        if (vo.getOperationType().equals("REDIRECT_TASK")) {
                            pd.put("updateTime",vo.getDate());
                            pd.put("status",DicType.instance_inapprove); //有这种type说明是审批中
                            dUserId = vo.getUserid();
                        }
                    }
                }
                if(StringUtils.isNotEmpty(dUserId)){
//                    Integer approveUserId = (Integer) dao.findForObject("ApproveMapper.getUserIdByDUserId",dUserId);
                    Integer approveUserId = 1;
                    if(approveUserId !=null){
                        pd.put("approveUserId",approveUserId);
                    }
                }

                String result = res.getProcessInstance().getResult();
                String status = res.getProcessInstance().getStatus();

                if (result.equals("agree")) {
                    if (status.equals("RUNNING")) {    //测试发现 同意可能是部分同意
                        pd.put("status",DicType.instance_inapprove);
//                        dao.update("ApproveMapper.updateProjStatus", pd);
                    }else {
                        pd.put("status", DicType.instance_agree);
//                        dao.update("ApproveMapper.updateProjStatus", pd);
                    }
                } else if (result.equals("refuse")) {
                    pd.put("status",DicType.instance_reject);
//                    dao.update("ApproveMapper.updateProjStatus",pd);
                } else {
                    if (status.equals("NEW") || status.equals("RUNNING")) {    //如果有status则应该是审批中75
                        if(StringUtils.isNotEmpty(pd.getString("status"))) {
//                            dao.update("ApproveMapper.updateProjStatus", pd);
                        }
                    } else if (status.equals("TERMINATED") || status.equals("CANCELED")) {//撤销中止按取消
                        pd.put("status",DicType.instance_cancel);
//                        dao.update("ApproveMapper.updateProjStatus",pd);
                    }
                }
            }
        }
    }

    @Override
    public void insertDeptAndUser() throws Exception {
        logger.info("--------------------开始拉取部门和用户数据----------------------");
        OapiDepartmentListResponse res = null;
        List<OapiDepartmentListResponse.Department> depts;
        try {
            res = DTConstant.getDepts();
        } catch (Exception e) {
            logger.error("userSimplelist获取失败",e);
            throw new Exception("userSimplelist获取失败");
        }
        if(DTConstant.resCode.equals(res.getErrcode())){
            depts = res.getDepartment();
            //次序需要查部门详情
        }else {
            throw new Exception("获取失败");
        }

        //清空数据
//        dao.update("DTUserMapper.delOrg",null);
        //部门信息插入数据库
//        dao.insert("DTUserMapper.pushDept",depts);
//        dao.update("DTUserMapper.updateDeptParent",null);
        logger.info("--------------------部门和用户数据拉取完毕----------------------");
        try {
            insertUser();
        }catch (Exception e){
            logger.error("拉取用户失败");
            throw new Exception();
        }
    }

    @Override
    public void insertUser() throws Exception {
        logger.info("--------------------开始拉取用户数据----------------------");
        //获取所有部门（库获取）
//        List<String> deptIds = (List<String>)dao.findForList("DTUserMapper.getDeptIds",null);
        List<String> deptIds = new ArrayList<>();
        Set<String> userIds = new HashSet<>();
        List<OapiUserGetResponse> userDetailList = new ArrayList<>();
        //获取部门成员
        for (String id : deptIds) {
            OapiUserSimplelistResponse res = null;
            try {
                res = DTConstant.userSimplelist(Long.valueOf(id));
            } catch (Exception e) {
                logger.error("userSimplelist获取失败",e);
                try {
                    res = DTConstant.userSimplelist(Long.valueOf(id));
                }catch (Exception e2) {
                    throw new Exception("userSimplelist获取失败");
                }
            }
            if (DTConstant.resCode.equals(res.getErrcode())) {
                List<OapiUserSimplelistResponse.Userlist> userlist = res.getUserlist();
                for (OapiUserSimplelistResponse.Userlist user : userlist) {
                    //获取成员详情
                    userIds.add(user.getUserid());
                }
            }
        }
        for(String userId: userIds){
            OapiUserGetResponse userRes = null;
            try {
                userRes = DTConstant.getUserDetailByUserId(userId);
            } catch (Exception e) {
                logger.error("getUserDetailByUserId获取失败:"+userId);
                try {
                    userRes = DTConstant.getUserDetailByUserId(userId);
                }catch (Exception e2) {
                    logger.error("getUserDetailByUserId获取失败:"+userId);
                    throw new Exception("getUserDetailByUserId获取失败");
                }
                logger.error("getUserDetailByUserId重新获取成功:"+userId);
            }
            if (DTConstant.resCode.equals(userRes.getErrcode())) {
                userDetailList.add(userRes);
            }
        }

//        dao.update("DTUserMapper.delUser",null);
        //成员信息插入数据库
//        dao.insert("DTUserMapper.pushUser",userDetailList);
        logger.info("--------------------用户数据插入完毕----------------------");
        logger.info("--------------------开始拉取deptuser数据----------------------");
//        List<PageData> userlist = ( List<PageData>)dao.findForList("DTUserMapper.getUserIdsAndUDs",null);
//        List<PageData> orglist = ( List<PageData>)dao.findForList("DTUserMapper.getOrgIdsAndODs",null);
        List<PageData> userlist = new ArrayList<>();
        List<PageData> orglist = new ArrayList<>();
        List<Map<String,Object>> deptUserList = new ArrayList<>();
        for(OapiUserGetResponse res: userDetailList){
            List<Long> depts = res.getDepartment();
            String duserId = res.getUserid();
            int userId = 0;
            for(PageData pd: userlist){
                if(pd.getString("duserId").equals(duserId)){
                    userId = pd.getInt("userId");
                    break;
                }
            }
            if (userId != 0) {
                Map<String, Object> map;
                for (int i = 0; i < depts.size(); i++) {
                    map = new HashMap<>();
                    map.put("userId", userId);
                    String orgId = "";
                    for (PageData pd : orglist) {
                        if (Long.valueOf(pd.getString("organizeId")).equals(depts.get(i))) {
                            orgId = pd.getString("orgId");
                            break;
                        }
                    }

                    map.put("deptId", orgId);
                    String isLeader = res.getIsLeaderInDepts();
                    JSONObject jo = JSON.parseObject(isLeader);
                    boolean isLea = (boolean) jo.get(depts.get(i).intValue());
                    if (isLea) {
                        map.put("isLea", 1);
                    } else {
                        map.put("isLea", 0);
                    }
                    deptUserList.add(map);
                }

            }
        }

        //清空数据
//        dao.update("DTUserMapper.delOrgU",null);
//        dao.insert("DTUserMapper.pushDeptUser",deptUserList);
        logger.info("--------------------deptuser数据插入结束----------------------");
    }

    @Override
    public void insertProj(Long startTime,boolean isInit) {
        PageData log = new PageData();
        logger.info("--------------------开始拉取立项申请数据----------------------");
        //数据量比较大，分批插入数据库

        Long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();

        List<OapiProcessinstanceGetResponse.ProcessInstanceTopVo> projList = new ArrayList<>();
        List<String> instanceId = new ArrayList<>();

        Set<String> projIds = new HashSet<>();
        try {
            if(null!=startTime) {
                DTConstant.getProjIds(projIds, startTime, endTime, 0L);
            }else{
                DTConstant.getProjIds(projIds, null, endTime, 0L);
            }
        } catch (Exception e) {
            e.printStackTrace();
            //这个时间段的数据重新拉取
            logger.error("项目拉取失败,请重新拉取本时间段的数据, 时间："+new Date(startTime)+"-"+new Date(endTime));
            log.put("handleId",startTime+"-"+endTime);
            log.put("logText","失败");
//            dao.insert("DTUserMapper.projlog",log);
        }
        for(String id: projIds){
            OapiProcessinstanceGetResponse res = null;
            try {
                res = DTConstant.getProjectDetail(id);
            } catch (Exception e) {
                e.printStackTrace();
                //获取失败  这个projId重新拉取 并判度结束时间验证
            }
            if(DTConstant.resCode.equals(res.getErrcode())){
                if(StringUtils.isNotEmpty(res.getProcessInstance().getResult())){
                    projList.add(res.getProcessInstance());
                    instanceId.add(id);
                }
            }else {
                //获取失败  这个projId重新拉取 并判度结束时间验证
                logger.error("项目Id"+id+"拉取失败, 时间："+new Date(startTime)+"-"+new Date(endTime));
                log.put("handleId","projId"+id+":"+ startTime+"-"+endTime);
                log.put("logText","项目导入失败");
//                dao.insert("DTUserMapper.projlog",log);
            }
        }

        //数据库插入projList
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> map;
//        List<PageData> userlist = ( List<PageData>)dao.findForList("DTUserMapper.getUserIdsAndUDs",null);
//        List<PageData> orglist = ( List<PageData>)dao.findForList("DTUserMapper.getOrgIdsAndODs",null);

        List<PageData> userlist = new ArrayList<>();
        List<PageData> orglist = new ArrayList<>();
        OapiProcessinstanceGetResponse.ProcessInstanceTopVo instance;
        for(int i=0;i<projList.size();i++){
            instance = projList.get(i);
            int userId = 0;
            for(PageData pd: userlist){
                if(pd.getString("duserId").equals(instance.getOriginatorUserid())){
                    userId = pd.getInt("userId");
                    break;
                }
            }
            String orgId = "";
            for (PageData pd: orglist){
                if(pd.getString("organizeId").equals(instance.getOriginatorDeptId())){
                    orgId = pd.getString("orgId");
                    break;
                }
            }
            map = new HashMap<>();
            map.put("instanceId",instanceId.get(i));
            if(instance.getResult().equals("agree")){
                map.put("checkState",1);

                Date date = instance.getCreateTime();
                map.put("createTime",date);
                map.put("createUserId",userId);
                map.put("orgId",orgId);
                map.put("updateTime",instance.getFinishTime());

                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                map.put("projectId",sdf.format(date)+""+userId);
                for(OapiProcessinstanceGetResponse.FormComponentValueVo vo: instance.getFormComponentValues()){
                    if(StringUtils.isNotEmpty(vo.getValue())&&!"null".equals(vo.getValue())) {
                        if (vo.getName().contains("项目名称")) {
                            map.put("projectName", vo.getValue());
                        }
                        if (vo.getName().contains("项目详细需求")) {
                            map.put("customersNeeds", vo.getValue());
                        }
                    }
                }
                list.add(map);

            }else {
//                map.put("checkState",0);
            }

        }
        if(isInit) {
//            dao.delete("DTUserMapper.delProj", null);
//            dao.delete("DTUserMapper.delProjInfo", null);
        }
        if(list!=null && !list.isEmpty()) {
//            dao.insert("DTUserMapper.pushProjApplication", list);
//            dao.insert("DTUserMapper.pushProjInfo", list);
            DTConstant.GETPROJSTARTTIME = endTime;
        }
        logger.info("--------------------立项申请数据插入结束----------------------");
        log.put("handleId", startTime+"-"+endTime);
        log.put("logText","正常,数据量:"+list.size());
//        dao.insert("DTUserMapper.projlog",log);
    }


}
